import os
from pathlib import Path
from docx import Document
from PIL import Image
from docx.oxml.ns import qn
from docx.text.paragraph import Paragraph
from docx.table import Table
import subprocess
import platform
if platform.system() == 'Windows':
    import win32com.client

class Word2MD:

    UPLOAD_FOLDER = "/home/skl_code/mypyprojects/word2md/words_in"
    def __init__(self, word_path, output_base="outputs"):
        # 初始化Word2MD类，传入word文件路径和输出目录
        self.word_path = self.validate_file_path(word_path)
        self.word_name = os.path.splitext(os.path.basename(self.word_path))[0]
        self.output_dir = os.path.join(output_base, self.word_name)
        self.images_dir = os.path.join(self.output_dir, "images")
        self.md_path = os.path.join(self.output_dir, f"{self.word_name}.md")
        self.create_directories()

    def create_directories(self):
        # 创建输出目录和图片目录
        os.makedirs(self.output_dir, exist_ok=True)
        os.makedirs(self.images_dir, exist_ok=True)

    def clean_path(self, path_str):
        # 清理路径字符串
        path_str = path_str.strip()
        path_str = path_str.strip('"').strip("'")
        if path_str.startswith(('r"', 'R"')):
            path_str = path_str[2:]
        if path_str.startswith(("r'", "R'")):
            path_str = path_str[2:]
        return path_str


    def convert_doc_to_docx(self,doc_path):
        # 将.doc文件转换为.docx文件
        try:
            abs_doc_path = os.path.abspath(str(doc_path))
            docx_path = abs_doc_path.replace('.doc', '.docx')
            if os.path.exists(docx_path):
                print(f"发现已存在的.docx文件: {docx_path}")
                return Path(docx_path)

            print(f"传入.doc文档，正在转换为.docx格式...")
            if platform.system() == 'Windows':
                word = win32com.client.Dispatch('Word.Application')
                try:
                    word.Visible = False
                    doc = word.Documents.Open(abs_doc_path)
                    doc.SaveAs2(docx_path, FileFormat=16)
                    doc.Close()
                finally:
                    word.Quit()
            elif platform.system() == 'Linux':

                if not os.path.isfile(abs_doc_path):
                    raise FileNotFoundError(f"The file {abs_doc_path} does not exist.")
                # 提取文件名（不包括扩展名）并构建新的 .docx 文件路径
                base_name = os.path.splitext(os.path.basename(abs_doc_path))[0]
                docx_filename = f"{base_name}.docx"
                docx_path = os.path.join(self.UPLOAD_FOLDER, docx_filename)


                subprocess.run(['libreoffice', '--headless', '--convert-to', 'docx', '--outdir', self.UPLOAD_FOLDER, abs_doc_path], check=True)
            else:
                raise ValueError("不支持的操作系统")

            if not os.path.exists(docx_path):
                raise ValueError(f"转换失败：未能生成.docx文件")

            print(f"转换.docx完成: {docx_path}")
            return Path(docx_path)
        except Exception as e:
            print(f"转换过程中的详细错误: {str(e)}")
            raise ValueError(f"转换.doc到.docx格式失败: {str(e)}")





    def validate_file_path(self, file_path):
        # 验证文件路径
        try:
            # 如果file_path是字符串，则清理路径
            if isinstance(file_path, str):
                clean_path_str = self.clean_path(file_path)
                path = Path(clean_path_str).resolve()
            else:
                path = file_path.resolve()

            if not path.exists():
                raise FileNotFoundError(f"文件不存在: {path}")
            if not path.is_file():
                raise ValueError(f"路径不是一个文件: {path}")
            if path.suffix.lower() not in ['.doc', '.docx']:
                raise ValueError(f"不支持的文件类型: {path.suffix}")

            if path.suffix.lower() == '.doc':
                path = self.convert_doc_to_docx(path)

            return path
        except Exception as e:
            raise ValueError(f"无效的文件路径: {file_path}\n错误: {str(e)}")

    def convert_table_to_md(self, table, image_dict):
        # 将表格转换为Markdown格式
        md_table = []
        header = [self.process_cell(cell, image_dict) for cell in table.rows[0].cells]
        md_table.append("| " + " | ".join(header) + " |")
        md_table.append("| " + " | ".join(["---"] * len(header)) + " |")
        for row in table.rows[1:]:
            row_data = [self.process_cell(cell, image_dict) for cell in row.cells]
            md_table.append("| " + " | ".join(row_data) + " |")
        return "\n".join(md_table)

    def process_cell(self, cell, image_dict):
        # 处理单元格内容
        cell_content = []
        for paragraph in cell.paragraphs:
            cell_content.extend(self.process_paragraph(paragraph, image_dict))
        return " ".join(cell_content).strip()

    def save_image(self, image_data, image_index):
        # 保存图片
        image_filename = f"image_{image_index}.png"
        image_path = os.path.join(self.images_dir, image_filename)
        with open(image_path, "wb") as img_file:
            img_file.write(image_data)
        return f"images/{image_filename}"

    def process_images(self, doc):
        # 处理图片
        image_index = 1
        image_dict = {}
        for rel in doc.part.rels.values():
            if "image" in rel.reltype:
                try:
                    image_path = self.save_image(rel.target_part.blob, image_index)
                    image_dict[rel.rId] = {'index': image_index, 'path': image_path}
                    image_index += 1
                except Exception as e:
                    print(f"Warning: Failed to save image {rel.rId}: {str(e)}")
        return image_dict

    def process_paragraph(self, paragraph, image_dict):
        content = []
        xml_str = str(paragraph._element.xml)
        for rId, img_info in image_dict.items():
            if rId in xml_str:
                content.append(f"![image_{img_info['index']}]({img_info['path']})")
        if paragraph.text.strip():
            content.append(paragraph.text.strip())
        return content

    def convert(self):
        print(f"Starting conversion of {self.word_path}")
        doc = Document(self.word_path)
        image_dict = self.process_images(doc)
        md_content = []
        for element in doc.element.body:
            if element.tag.endswith('p'):
                paragraph = Paragraph(element, doc)
                if paragraph.style.name.startswith('Heading'):
                    try:
                        level = int(paragraph.style.name[-1])
                        md_content.append(f"{'#' * level} {paragraph.text}")
                    except ValueError:
                        md_content.append(f"# {paragraph.text}")
                else:
                    content = self.process_paragraph(paragraph, image_dict)
                    md_content.extend(content)
            elif element.tag.endswith('tbl'):
                table = Table(element, doc)
                md_content.append(self.convert_table_to_md(table, image_dict) + "\n\n")
        with open(self.md_path, 'w', encoding='utf-8') as md_file:
            md_file.write('\n'.join(md_content))
        print("Conversion completed")

    def run(self):
        self.convert()
        print(f"输出目录: {self.output_dir}")
        print(f"Markdown文件: {self.md_path}")
        print(f"图片目录: {self.images_dir}")

if __name__ == "__main__":
    # word_path = "/home/user/Documents/biaoxianxingshi-3.docx"
    word_path = '/home/user/Documents/指南-电网.doc'
    word_path = Path(word_path)
    converter = Word2MD(word_path)
    converter.run()
